# Copyright (c) 2022 Robert Bosch GmbH and Microsoft Corporation
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0

"""A sample skeleton vehicle app."""

import asyncio
import json
import logging

from sdv.util.log import (  # type: ignore
    get_opentelemetry_log_factory,
    get_opentelemetry_log_format,
)

from sdv.vehicle_app import VehicleApp, subscribe_topic
from vehicle import Vehicle  # type: ignore


# Configure the VehicleApp logger with the necessary log config and level.
logging.setLogRecordFactory(get_opentelemetry_log_factory())
logging.basicConfig(format=get_opentelemetry_log_format())
logging.getLogger().setLevel("DEBUG")
logger = logging.getLogger(__name__)

GET_BEAM_REQUEST_TOPIC = "frontlightcontrol/setBeam/request"
GET_BEAM_RESPONSE_TOPIC = "frontlightcontrol/setBeam/response"


class FrontLightControlApp(VehicleApp):

    def __init__(self, vehicle_client: Vehicle):
        # SampleApp inherits from VehicleApp.
        super().__init__()
        self.Vehicle = vehicle_client
        self.flag = True

    async def on_start(self):
        """Run when the vehicle app starts"""
        # This method will be called by the SDK when the connection to the
        # Vehicle DataBroker is ready.
        # Here you can subscribe for the Vehicle Signals update (e.g. Vehicle beam).
        loop = asyncio.get_running_loop()
        loop.create_task(self.on_timer())

    async def on_timer(self):
        while 1:
            logging.debug("task loopping ...")
            await self.Vehicle.Body.Lights.IsLowBeamOn.set(self.flag)
            self.flag = not self.flag
            # logger.info('8**********')
            logger.info('flag is : %s', self.flag)
            await asyncio.sleep(0.5)

    @subscribe_topic(GET_BEAM_REQUEST_TOPIC)
    async def on_get_beam_request_received(self, data_str: str) -> None:

        logger.debug(
            "PubSub event for the Topic: %s -> is received with the data: %s",
            GET_BEAM_REQUEST_TOPIC,
            data_str,
        )

        beam_res = (await self.Vehicle.Body.Lights.IsLowBeamOn.get()).value

        await self.publish_event(
            GET_BEAM_RESPONSE_TOPIC,
            json.dumps(
                {
                    "result": {
                        "status": 0,
                        "message": f"""Current beam = {beam_res}""",
                    },
                }
            ),
        )
